import { Nodes, dom } from '@knno/dom';
import { Action } from '../action/action';
import { PopupPosition, Popup, Pos } from '../popup/popup';
import { button } from '../button/button';
import { DICT } from '../../dict';

export type OpenSelectOptions = {
	refer?: Nodes;
	useAction?: boolean;
	focus?: boolean;
	popupPosition?: PopupPosition | Pos;
	noIndicator?: boolean;
	width?: number | string;
	extraClass?: string;
	title?: string;
	noActionBar?: boolean;
};

export function isMobile(): boolean {
	return document.documentElement.offsetWidth <= 500;
}

type Callback = () => void;

interface AdaptivePopupHandler {
	readonly isAction: boolean;
	close(): void;
	onOpen(callback: Callback): this;
	onClose(callback: Callback): this;
	onOK(callback: Callback): this;
}

export class AdaptivePopup {
	protected static openAction(
		container: Nodes,
		title: string,
		onOpen: () => void,
		onClose: () => void,
		onOK: () => void,
		extraClass?: string,
		noBar?: boolean
	) {
		Action.show(container)
			.addClass(extraClass ?? '')
			.on('open', onOpen)
			.on('close', onClose)
			.title(title)
			.onOK(() => {
				onOK();
			})
			.noBar(!!noBar);
		return {
			close() {
				Action.close();
			},
		};
	}

	protected static openPopup(
		refer: Nodes,
		container: Nodes,
		position: PopupPosition | Pos,
		noIndicator: boolean,
		focus: boolean,
		width: number | string | undefined | 'auto' | (() => number | string),
		onOpen: () => void,
		onClose: () => void,
		extraClass?: string
	) {
		container.css({
			width: typeof width === 'string' ? width : typeof width === 'number' ? width + 'px' : refer.innerWidth() + 'px',
		});
		const pop = Popup.create(container)
			.noIndicator(noIndicator)
			.addClass(extraClass ?? '')
			.on('open', onOpen)
			.on('close', onClose)
			.show(refer, position, focus);
		return {
			close() {
				pop.close();
			},
		};
	}

	static show(
		container: Nodes,
		{
			refer,
			useAction = false,
			focus = false,
			popupPosition = 'bottom-left',
			width,
			extraClass = 'no-h-padding',
			title,
			noActionBar = false,
			noIndicator = false,
		}: OpenSelectOptions
	): AdaptivePopupHandler {
		let onOpen: Callback | undefined;
		let onOk: Callback | undefined;
		let onClose: Callback | undefined;
		let pop: { close: () => void };
		function makeBox(): Nodes {
			return dom
				.div()
				.css({ display: 'flex', flexDirection: 'column' })
				.append(
					container,
					button()
						.text(DICT.ok)
						.type('primary')
						.css({ margin: '1em' })
						.on('click', () => {
							onOk?.();
						})
				);
		}
		let isAction = false;
		if ((isMobile() && useAction) || refer === undefined) {
			isAction = true;
			pop = this.openAction(
				container,
				title ?? '',
				() => {
					onOpen?.();
				},
				() => {
					onClose?.();
				},
				() => {
					onOk?.();
				},
				extraClass,
				noActionBar
			);
		} else {
			const box = noActionBar ? container : makeBox();
			pop = this.openPopup(
				refer,
				box,
				popupPosition,
				noIndicator,
				focus,
				width,
				() => {
					onOpen?.();
				},
				() => {
					onClose?.();
				},
				extraClass
			);
		}
		return {
			isAction,
			...pop,
			onClose(callback) {
				onClose = callback;
				return this;
			},
			onOpen(callback) {
				onOpen = callback;
				return this;
			},
			onOK(callback) {
				onOk = callback;
				return this;
			},
		};
	}
}
